package com.leoren.run.activity.run;


import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AlertDialog;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.amap.api.maps.AMap;
import com.amap.api.maps.MapView;
import com.amap.api.maps.SupportMapFragment;
import com.amap.api.maps.model.BitmapDescriptorFactory;
import com.amap.api.maps.model.LatLng;
import com.amap.api.maps.model.Marker;
import com.amap.api.maps.model.MarkerOptions;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.core.SuggestionCity;
import com.amap.api.services.help.Inputtips;
import com.amap.api.services.help.InputtipsQuery;
import com.amap.api.services.help.Tip;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.route.BusRouteResult;
import com.amap.api.services.route.DrivePath;
import com.amap.api.services.route.DriveRouteResult;
import com.amap.api.services.route.RideRouteResult;
import com.amap.api.services.route.RouteSearch;
import com.amap.api.services.route.WalkRouteResult;
import com.bumptech.glide.RequestBuilder;
import com.google.gson.Gson;
import com.leoren.run.R;
import com.leoren.run.common.ResponseCode;
import com.leoren.run.common.ServerResponse;
import com.leoren.run.common.UrlConstants;
import com.leoren.run.log.L;
import com.leoren.run.utils.GsonUtil;
import com.leoren.run.utils.Http.OkHttp.CommonOkHttpClient;
import com.leoren.run.utils.Http.OkHttp.exception.OkHttpException;
import com.leoren.run.utils.Http.OkHttp.listener.DisposeDataHandle;
import com.leoren.run.utils.Http.OkHttp.listener.DisposeDataListener;
import com.leoren.run.utils.Http.OkHttp.request.CommonRequest;
import com.leoren.run.utils.ToastUtil;
import com.leoren.run.utils.mapApi.AMapUtil;
import com.leoren.run.utils.mapApi.overlay.PoiOverlay;
import com.leoren.run.utils.mapApi.overlay.DrivingRouteOverlay;
import com.leoren.run.vo.RunMapRouteVo;
import com.leoren.run.vo.RunRouteVo;
import com.leoren.run.vo.WayPoint;
import com.leoren.run.vo.pojo.RunMap;

import java.util.ArrayList;
import java.util.List;

import okhttp3.FormBody;
import okhttp3.Request;
import okhttp3.RequestBody;

/**
 * 手机制图界面
 */
public class CreateMapActivity extends FragmentActivity implements AMap.OnMarkerClickListener, AMap.InfoWindowAdapter, TextWatcher, PoiSearch.OnPoiSearchListener, View.OnClickListener, Inputtips.InputtipsListener,AMap.OnMapClickListener, AMap.OnMarkerDragListener, RouteSearch.OnRouteSearchListener {

    private MapView mapView;

    private Button searchBtn;
    private Button nextBtn;

    private AMap aMap;
    private AutoCompleteTextView searchText;
    private String keyWord = "";
    private ProgressDialog progDialog = null;
    private EditText editText;
    private PoiResult poiResult;
    private int currentPage = 0;
    private PoiSearch.Query query;
    private PoiSearch poiSearch;

    private Button publishMapBtn;
    private Button confirmBtn;
    private Button clearBtn;

    //路径部分
    private List<Marker> markerList;
    private MarkerOptions markerOptions;
    private int markerSize = 0;

    //获得路径部分
    private RouteSearch routeSearch;
    private DriveRouteResult routeResult;
    private final int ROUTE_TYPE_DRIVE = 2;
    private List<LatLonPoint> passedByPoints;

    private String province = "北京市";
    private String city = "北京市";
    private String district = "东城区";
    private RunMapRouteVo runMap;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_create_map);

        init();
    }

    private void init(){
        if (aMap == null) {
            aMap = ((SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map)).getMap();
            setUpMap();
        }
    }

    /**
     * 初始化地图各项控件
     */
    private void setUpMap(){
        searchBtn = findViewById(R.id.create_searchButton);
        nextBtn = findViewById(R.id.create_nextButton);
        publishMapBtn = findViewById(R.id.publish_map_btn);

        confirmBtn = findViewById(R.id.confirm_btn);
        clearBtn = findViewById(R.id.clear_btn);

        searchBtn.setOnClickListener(this);
        nextBtn.setOnClickListener(this);
        publishMapBtn.setOnClickListener(this);
        confirmBtn.setOnClickListener(this);
        clearBtn.setOnClickListener(this);

        searchText = findViewById(R.id.create_keyWord);
        editText = findViewById(R.id.create_city);


        searchText.addTextChangedListener(this);
        editText = findViewById(R.id.create_city);
        aMap.setOnMarkerClickListener(this);
        aMap.setInfoWindowAdapter(this);
        aMap.setOnMapClickListener(this);
        aMap.setOnMarkerDragListener(this);
        
        routeSearch = new RouteSearch(this);
        routeSearch.setRouteSearchListener(this);

    }

    /**
     * 询问是否发布创建好的地图
     */
    private void publishMap(){
        View view = getLayoutInflater().inflate(R.layout.edit_runmap_layout, null);
        final EditText editText = view.findViewById(R.id.edittext_runmap);
        new AlertDialog.Builder(this).setView(view)
                .setPositiveButton("确定", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialogInterface, int i) {
                        String runMapName = editText.getText().toString().trim();
                        startPublishRunMap(runMapName);

                    }
                }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialogInterface, int i) {

            }
        }).show();

    }

    /**
     * 发布创建好的地图
     * @param runMapName
     */
    private void startPublishRunMap(String runMapName) {
        runMap.setName(runMapName);
        L.e("runMap data" + GsonUtil.GenerateJsonStr(runMap));
        RequestBody body = new FormBody.Builder()
                .add("runMap", GsonUtil.GenerateJsonStr(runMap))
                .build();
        final Request request = CommonRequest.createPostRequest(UrlConstants.CREATE_MAP, body);
        CommonOkHttpClient.post(request, new DisposeDataHandle(new DisposeDataListener() {
            @Override
            public void onSuccess(String responseStr) {
                L.e("response = " + responseStr);
                ServerResponse response = GsonUtil.formatJsonToServerResponse(responseStr);
                if(response == null || !response.isSuccess()){
                    onFailure(new OkHttpException(ResponseCode.ERROR.getCode(), ResponseCode.NETWORK_ERROR.getValue()));
                }else {
                    ToastUtil.MakeToast(response.getMsg());
                }

            }

            @Override
            public void onFailure(OkHttpException e) {
                ToastUtil.MakeToast(e.getMsg().toString());
            }
        }));

    }

    /**
     * 点击地图添加一个Marker 多个Marker构成一条路经
     * @param latLng
     */
    private void addMapRouteMarker(LatLng latLng){
        L.e("设置marker" + markerSize + "坐标为" + latLng.toString());
        Marker marker = aMap.addMarker(new MarkerOptions().position(latLng).title("经纬度").snippet(latLng.latitude + ";" + latLng.longitude).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)).draggable(true));
        if(markerList == null){
            markerList = new ArrayList<>();
        }
        marker.setObject(markerSize);
        markerList.add(marker);
        markerSize++;
    }

    /**
     * 根据设置好的多个Marker进行路径查询请求
     */
    private void confirmMap(){
        if(markerSize <= 1){
            ToastUtil.MakeToast("请最少设置起点和终点两个点");
            return;
        }else if(markerSize > 16){
            ToastUtil.MakeToast("最多设置16个点");
            return;
        }
        LatLng firstMarker = markerList.get(0).getPosition();
        LatLng endMarker = markerList.get(markerSize - 1).getPosition();
        LatLonPoint startPoint = new LatLonPoint(firstMarker.latitude, firstMarker.longitude);
        LatLonPoint endPoint = new LatLonPoint(endMarker.latitude, endMarker.longitude);
        showProgressDialog();
        getPassPoint();
        RouteSearch.FromAndTo fromAndTo = new RouteSearch.FromAndTo(startPoint, endPoint);
        RouteSearch.DriveRouteQuery query = new RouteSearch.DriveRouteQuery(fromAndTo, RouteSearch.DrivingDefault, passedByPoints,
                null, "");// 第一个参数表示路径规划的起点和终点，第二个参数表示驾车模式，第三个参数表示途经点，第四个参数表示避让区域，第五个参数表示避让道路
        routeSearch.calculateDriveRouteAsyn(query);
    }

    /**
     * 根据Marker获取经过点列表
     */
    private void getPassPoint(){
        if(passedByPoints == null){
            passedByPoints = new ArrayList<>();
        }
        for(int i = 1; i < markerSize-1; i++){
            LatLng latLng = markerList.get(i).getPosition();
            passedByPoints.add(new LatLonPoint(latLng.latitude, latLng.longitude));
        }
    }

    /**
     * 清除地图上已经选好的Marker信息
     */
    private void clearMapMarkers(){
        aMap.clear();
        markerSize = 0;
    }



    /**
     * 点击搜索按钮
     */
    private void searchButton(){
        keyWord = AMapUtil.checkEditText(searchText);
        if("".equals(keyWord)){
            ToastUtil.MakeToast("请搜索关键字");
            return;
        }else {
            doSearchQuery();
        }
    }

    /**
     * 开始进行poi搜索
     */
    protected void doSearchQuery() {
        showProgressDialog();// 显示进度框
        currentPage = 0;
        query = new PoiSearch.Query(keyWord, "", editText.getText().toString());// 第一个参数表示搜索字符串，第二个参数表示poi搜索类型，第三个参数表示poi搜索区域（空字符串代表全国）
        query.setPageSize(10);// 设置每页最多返回多少条poiitem
        query.setPageNum(currentPage);// 设置查第一页
        query.setCityLimit(true);

        poiSearch = new PoiSearch(this, query);
        poiSearch.setOnPoiSearchListener(this);
        poiSearch.searchPOIAsyn();
    }

    /**
     * 点击下一页按钮
     */
    public void nextButton() {
        if (query != null && poiSearch != null && poiResult != null) {
            if (poiResult.getPageCount() - 1 > currentPage) {
                currentPage++;
                query.setPageNum(currentPage);// 设置查后一页
                poiSearch.searchPOIAsyn();
            } else {
                ToastUtil.MakeToast(R.string.no_result);
            }
        }
    }


    @Override
    public void onMarkerDragStart(Marker marker) {

    }

    @Override
    public void onMarkerDrag(Marker marker) {

    }

    /**
     * Marker拖拽以后回调
     * @param marker
     */
    @Override
    public void onMarkerDragEnd(Marker marker) {
        int position = (int) marker.getObject();
        L.e("更改之后marker" + position + "的坐标为 = ===" + marker.getPosition().toString());

        markerList.set(position, marker);
    }

    @Override
    public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {

    }

    /**
     * 详细地理位置输入内容更改时回调
     * @param charSequence
     * @param i
     * @param i1
     * @param i2
     */
    @Override
    public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
        String newText = charSequence.toString().trim();
        if (!AMapUtil.IsEmptyOrNullString(newText)) {
            InputtipsQuery inputquery = new InputtipsQuery(newText, editText.getText().toString());
            Inputtips inputTips = new Inputtips(CreateMapActivity.this, inputquery);
            inputTips.setInputtipsListener(this);
            inputTips.requestInputtipsAsyn();
        }
    }

    @Override
    public void afterTextChanged(Editable editable) {

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.create_searchButton:
                searchButton();
                break;
            case R.id.create_nextButton:
                nextButton();
                break;
            case R.id.publish_map_btn:
                publishMap();
                break;
            case R.id.confirm_btn:
                confirmMap();
                break;
            case R.id.clear_btn:
                clearMapMarkers();
                break;
            default:
                break;
        }
    }

    @Override
    public void onMapClick(LatLng latLng) {
        addMapRouteMarker(latLng);
    }

    /**
     * 设置Marker 数据
     * @param marker
     * @return
     */
    @Override
    public View getInfoWindow(final Marker marker) {
        View view = getLayoutInflater().inflate(R.layout.poikeywordsearch_uri, null);
        TextView title = view.findViewById(R.id.title);
        title.setText(marker.getTitle());
        TextView snippet = view.findViewById(R.id.snippet);
        snippet.setText(marker.getSnippet());
        return view;
    }

    @Override
    public View getInfoContents(Marker marker) {
        return null;
    }

    /**
     * marker 点击事件
     * @param marker
     * @return
     */
    @Override
    public boolean onMarkerClick(Marker marker) {
        marker.showInfoWindow();
        return false;
    }

    @Override
    public void onGetInputtips(List<Tip> tipList, int rCode) {
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {// 正确返回
            List<String> listString = new ArrayList<String>();
            for (int i = 0; i < tipList.size(); i++) {
                listString.add(tipList.get(i).getName());
            }
            ArrayAdapter<String> aAdapter = new ArrayAdapter<String>(
                    getApplicationContext(),
                    R.layout.route_inputs, listString);
            searchText.setAdapter(aAdapter);
            aAdapter.notifyDataSetChanged();
        } else {
            ToastUtil.showerror(CreateMapActivity.this, rCode);
        }

    }

    /**
     * 根据输入信息显示周围位置信息
     */
    @Override
    public void onPoiSearched(PoiResult result, int rCode) {
        dissmissProgressDialog();
        if (rCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getQuery() != null) {// 搜索poi的结果
                if (result.getQuery().equals(query)) {// 是否是同一条
                    poiResult = result;
                    PoiItem item = result.getPois().get(0);
                    province = item.getProvinceName();
                    city = item.getCityName();
                    district = item.getAdName();
                    // 取得搜索到的poiitems有多少页
                    List<PoiItem> poiItems = poiResult.getPois();// 取得第一页的poiitem数据，页数从数字0开始
                    List<SuggestionCity> suggestionCities = poiResult
                            .getSearchSuggestionCitys();// 当搜索不到poiitem数据时，会返回含有搜索关键字的城市信息

                    if (poiItems != null && poiItems.size() > 0) {
                        aMap.clear();// 清理之前的图标
                        PoiOverlay poiOverlay = new PoiOverlay(aMap, poiItems);
                        poiOverlay.removeFromMap();
                        poiOverlay.addToMap();
                        poiOverlay.zoomToSpan();
                    } else if (suggestionCities != null
                            && suggestionCities.size() > 0) {
                        showSuggestCity(suggestionCities);
                    } else {
                        ToastUtil.MakeToast(R.string.no_result);
                    }
                }
            } else {
                ToastUtil.MakeToast(R.string.no_result);
            }
        } else {
            ToastUtil.showerror(CreateMapActivity.this, rCode);
        }
    }

    /**
     * poi没有搜索到数据，返回一些推荐城市的信息
     */
    private void showSuggestCity(List<SuggestionCity> cities) {
        String infomation = "推荐城市\n";
        for (int i = 0; i < cities.size(); i++) {
            infomation += "城市名称:" + cities.get(i).getCityName() + "城市区号:"
                    + cities.get(i).getCityCode() + "城市编码:"
                    + cities.get(i).getAdCode() + "\n";
        }
        ToastUtil.MakeToast( infomation);

    }

    @Override
    public void onPoiItemSearched(PoiItem poiItem, int i) {

    }

    /**
     * 显示进度框
     */
    private void showProgressDialog() {
        if (progDialog == null)
            progDialog = new ProgressDialog(this);
        progDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);
        progDialog.setIndeterminate(false);
        progDialog.setCancelable(false);
        progDialog.setMessage("正在搜索:");
        progDialog.show();
    }

    /**
     * 隐藏进度框
     */
    private void dissmissProgressDialog() {
        if (progDialog != null) {
            progDialog.dismiss();
        }
    }

    @Override
    public void onBusRouteSearched(BusRouteResult busRouteResult, int i) {
        
    }

    /**
     * 获取路径信息后回调
     * @param result
     * @param errorCode
     */
    @Override
    public void onDriveRouteSearched(DriveRouteResult result, int errorCode) {
        dissmissProgressDialog();
        aMap.clear();// 清理地图上的所有覆盖物
        if (errorCode == AMapException.CODE_AMAP_SUCCESS) {
            if (result != null && result.getPaths() != null) {
                if (result.getPaths().size() > 0) {
                    routeResult = result;
                    final DrivePath drivePath = routeResult.getPaths()
                            .get(0);
                    DrivingRouteOverlay drivingRouteOverlay = new DrivingRouteOverlay(
                            CreateMapActivity.this, aMap, drivePath,
                            routeResult.getStartPos(),
                            routeResult.getTargetPos(), null);
                    drivingRouteOverlay.setNodeIconVisibility(false);//设置节点marker是否显示
                    drivingRouteOverlay.setIsColorfulline(true);//是否用颜色展示交通拥堵情况，默认true
                    drivingRouteOverlay.removeFromMap();
                    drivingRouteOverlay.addToMap();
                    drivingRouteOverlay.zoomToSpan();
                    float dis = drivePath.getDistance();
                    int dur = (int) drivePath.getDuration();
                    double time = dis / 7000 * 3600;
                    int timeInt = (int)time;
                    runMap = AMapUtil.generateRunMap(result, dis, timeInt, province, city, district);
                    L.e("生成数据是" + GsonUtil.GenerateJsonStr(runMap));
                } else if (result != null && result.getPaths() == null) {
                    ToastUtil.MakeToast(R.string.no_result);
                }

            } else {
                ToastUtil.MakeToast(R.string.no_result);
            }
        } else {
            ToastUtil.showerror(this.getApplicationContext(), errorCode);
        }
    }

    @Override
    public void onWalkRouteSearched(WalkRouteResult walkRouteResult, int i) {

    }

    @Override
    public void onRideRouteSearched(RideRouteResult rideRouteResult, int i) {

    }
}
